#include "../source/vlib.h"
#include <stdio.h>

static void test_create(void)
{
    str_t ss = str("Hello str!");
    str_t copy = str(ss);
    
    printf("ss: %s\r\n", str_c_str(ss));
    printf("copy: %s\r\n", _S(copy));

    _str(copy);
    _str(ss);
}

static void test_assign(void)
{
    str_t s1 = str("Hello str!");
    str_t s2 = str("");
    
    printf("s1: %s\r\n", _S(s1));
    printf("s2: %s\r\n", _S(s2));
    str_assign(s1, "This is assign function!");
    str_assign(s2, s1);
    printf("s1: %s\r\n", _S(s1));
    printf("s2: %s\r\n", _S(s2));

    _str(s1);
    _str(s2);
}

static void test_append(void)
{
    str_t email = str("");
    str_t name = str("Lamdonn");
    str_t domain = str("163");
    
    str_append(email, name, "@", domain, ".com");
    printf("email: %s\r\n", _S(email));

    _str(email);
    _str(name);
    _str(domain);
}

static void test_insert(void)
{
    str_t ss = str("0123456");

    str_insert(ss, 3, "|insert|");
    printf("ss: %s\r\n", _S(ss));

    _str(ss);
}

static void test_erase(void)
{
    str_t ss = str("0123456789");

    str_erase(ss, 3, 5);
    printf("ss: %s\r\n", _S(ss));

    _str(ss);
}

static void test_compare(void)
{
    str_t ss = str("01234");
    str_t copy = str(ss);

    printf("compare: %d\r\n", str_compare(ss, copy));
    printf("compare: %d\r\n", str_compare(ss, "01233"));
    printf("compare: %d\r\n", str_compare(ss, "012345"));

    _str(ss);
    _str(copy);
}

static void test_at(void)
{
    str_t ss = str("0123456789");

    printf("ss[5] = %c\r\n", str_at(ss, 5));
    printf("ss[100] = %c\r\n", str_at(ss, 100));
    str_at(ss, 0) = 'A';
    str_at(ss, -1) = 'B';
    printf("ss: %s\r\n", _S(ss));

    _str(ss);
}

static void test_substr(void)
{
    str_t ss = str("0123456789");
    str_t sub = str_substr(ss, 4, 2);

    printf("ss: %s\r\n", str_c_str(ss));
    printf("sub: %s\r\n", str_c_str(sub));

    _str(ss);
    _str(sub);
}

static void test_push_pop(void)
{
    str_t ss = str("0123456789");

    printf("pop %c\r\n", str_pop_back(ss));
    printf("pop %c\r\n", str_pop_back(ss));
    str_push_back(ss, 'A');
    printf("ss: %s\r\n", _S(ss));

    _str(ss);
}

static void test_len_cap(void)
{
    str_t ss = str("012");

    printf("length = %d, capacity = %d\r\n", str_length(ss), str_capacity(ss));
    str_assign(ss, "0123456789");
    printf("length = %d, capacity = %d\r\n", str_length(ss), str_capacity(ss));

    _str(ss);
}

static void test_reverse(void)
{
    str_t ss = str("0123456789");

    str_reverse(ss, 2, 8);
    printf("ss = %s\r\n", str_c_str(ss));

    _str(ss);
}

static void test_swap(void)
{
    str_t ss = str("This is ss!");
    str_t swap = str("This is swap!");

    str_swap(ss, swap);
    printf("ss = %s\r\n", str_c_str(ss));
    printf("swap = %s\r\n", str_c_str(swap));

    _str(ss);
    _str(swap);
}

static void test_copy(void)
{
    str_t ss = str("0123456789");
    char array[32] = { 0 };
    int length = 0;

    length = str_copy(ss, 5, sizeof(array), array);
    array[length] = '\0';
    printf("length = %d, copy: %s\r\n", length, array);

    _str(ss);
}

static void test_replace(void)
{
    str_t ss = str("0123456789");

    str_replace(ss, 5, 1, "|replace|");
    printf("ss: %s\r\n", str_c_str(ss));

    _str(ss);
}

static void test_find(void)
{
    str_t ss = str("0001200000000003210");

    printf("find: %d\r\n", str_find(ss, "12", 0));
    printf("rfind: %d\r\n", str_rfind(ss, "032", str_length(ss) - 1));
    printf("find: %d\r\n", str_find(ss, "555", 0));

    _str(ss);
}

static void test_find_of(void)
{
    str_t ss = str("C:/workspace/project/C/vlib/main.c");
    str_t pan = NULL;
    str_t filename = NULL;

    pan = str_substr(ss, 0, str_find_first_of(ss, ":", 0));
    filename = str_substr(ss, str_find_last_of(ss, "\\/", str_length(ss)-1) + 1, str_length(ss));
    printf("pan: %s\r\n", str_c_str(pan));
    printf("filename: %s\r\n", str_c_str(filename));

    _str(ss);
    _str(pan);
    _str(filename);
}

static void test_format(void)
{
    str_t ss = str("");
    str_t pp = str("format");

    str_format(ss, "float=%.3f, int=%d, char=%c, string: %s %s!", 3.14159, 123, 'V', pp, "function");
    printf("ss: %s\r\n", str_c_str(ss));

    _str(ss);
    _str(pp);
}

void test_str(void)
{
    // test_create();
    // test_assign();
    // test_append();
    // test_insert();
    // test_erase();
    // test_compare();
    // test_at();
    // test_substr();
    // test_push_pop();
    // test_len_cap();
    // test_reverse();
    // test_swap();
    // test_copy();
    // test_replace();
    // test_find();
    // test_find_of();
    test_format();

    #if 0
    str_t ss = str("Hello str!");
    char buf[64] = {0};
    int len = 0;
    
    printf("ss: %s\r\n", _S(ss));
    printf("append: %s\r\n", _S(str_append(ss, " world!", " AAA", " BBBB")));
    // printf("insert: %s\r\n", _S(str_insert(ss, 2, ss)));
    // printf("erase: %s\r\n", _S(str_erase(ss, 0, str_length(ss))));
    printf("length = %d, capacity = %d\r\n", str_length(ss), str_capacity(ss));
    printf("compare %d\r\n", str_compare(ss, "HelloA"));
    printf("at = %c\r\n", str_at(ss, 0));
    printf("substr: %s\r\n", _S(str_substr(ss, 0, str_length(ss))));
    printf("format: %s\r\n", _S(str_format(ss, "ZhangSan %s", "ABC")));
    printf("find: %d\r\n", str_find(ss, "an", 0));
    printf("rfind: %d\r\n", str_rfind(ss, "C", str_length(ss) - 1));
    printf("first of: %d\r\n", str_find_first_of(ss, "abch", 0));
    printf("first not of: %d\r\n", str_find_first_not_of(ss, "Zhga", 0));
    printf("last of: %d\r\n", str_find_last_of(ss, "abch", str_length(ss) - 1));
    printf("last not of: %d\r\n", str_find_last_not_of(ss, "ZABC", str_length(ss) - 1));
    printf("assign: %s\r\n", _S(str_assign(ss, "0123456789")));
    printf("reverse: %s\r\n", _S(str_reverse(ss, 2, 8)));
    // printf("replace: %s\r\n", _S(str_replace(ss, 2, 0, ss)));
    len = str_copy(ss, 5, sizeof(buf), buf);
    buf[len] = 0;
    printf("copy: %s\r\n", buf);
    printf("front = %c, back = %c\r\n", str_front(ss), str_back(ss));
    str_push_back(ss, '#');
    printf("pop back: %c\r\n", str_pop_back(ss));
    // str_clear(ss);
    // printf("clear: %s\r\n", _S(ss));

    printf("---------------------------------------\r\n");

    str_t copy = str(ss);
    printf("copy: %s\r\n", _S(copy));

    _str(ss);
    _str(copy);

    printf("---------------------------------------\r\n");

    ss = str("f46s4dg4a89g48fdg4g32g5897gt");
    int index = 0;

    printf("ss: %s\r\n", _S(ss));
    index = str_find_first_not_of(ss, "0123456789", 0);
    while (index != str_npos) 
    {
        str_at(ss, index) = '*';
        index = str_find_first_not_of(ss, "0123456789", index + 1);
    }
    printf("ss: %s\r\n", _S(ss));

    str_assign(ss, "D:/software/workspace/vlib/vlib_single/main.c");

    str_t filename = str_substr(ss, str_find_last_of(ss, "/\\", str_length(ss) - 1) + 1, str_length(ss));
    str_t directory = str_substr(ss, 0, str_find_last_of(ss, "/\\", str_length(ss) - 1));
    printf("filename: %s\r\n", _S(filename));
    printf("directory: %s\r\n", _S(directory));

    str_t pp = str("format");
    str_format(ss, "Hello str! %s %s! %p, %.6f", pp, "function", ss, 3.1415926);
    printf("ss: %s\r\n", _S(ss));
    _str(pp);

    _str(ss);
    _str(filename);
    _str(directory);
    #endif 
}
